package service

import (
	"context"
	"errors"
	"time"

	"github.com/golang-jwt/jwt/v5"
	"golang.org/x/crypto/bcrypt"

	"Data-API-MCP/backend/configs"
	"Data-API-MCP/backend/internal/domain/entity"
	"Data-API-MCP/backend/internal/domain/repository"
)

// userServiceImpl 用户服务实现
type userServiceImpl struct {
	userRepo repository.UserRepository
	config   *configs.Config
}

// UserService 用户服务接口
type UserService interface {
	// 注册用户
	Register(ctx context.Context, username, password, email string) (*entity.User, error)
	// 登录
	Login(ctx context.Context, username, password string) (string, error)
	// 获取用户信息
	GetUserInfo(ctx context.Context, id uint) (*entity.User, error)
	// 更新用户信息
	UpdateUserInfo(ctx context.Context, user *entity.User) error
	// 修改密码
	ChangePassword(ctx context.Context, id uint, oldPassword, newPassword string) error
	// 获取用户列表
	ListUsers(ctx context.Context, offset, limit int) ([]*entity.User, int64, error)
	// 删除用户
	DeleteUser(ctx context.Context, id uint) error
}

// NewUserService 创建用户服务实例
func NewUserService(userRepo repository.UserRepository, config *configs.Config) UserService {
	return &userServiceImpl{
		userRepo: userRepo,
		config:   config,
	}
}

// Register 用户注册
func (s *userServiceImpl) Register(ctx context.Context, username, password, email string) (*entity.User, error) {
	// 检查用户名是否已存在
	if _, err := s.userRepo.FindByUsername(ctx, username); err == nil {
		return nil, errors.New("用户名已存在")
	}

	// 检查邮箱是否已存在
	if _, err := s.userRepo.FindByEmail(ctx, email); err == nil {
		return nil, errors.New("邮箱已存在")
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		return nil, err
	}

	// 创建用户
	user := &entity.User{
		Username: username,
		Password: string(hashedPassword),
		Email:    email,
		Status:   1,
	}

	if err := s.userRepo.Create(ctx, user); err != nil {
		return nil, err
	}

	return user, nil
}

// Login 用户登录
func (s *userServiceImpl) Login(ctx context.Context, username, password string) (string, error) {
	// 查找用户
	user, err := s.userRepo.FindByUsername(ctx, username)
	if err != nil {
		return "", errors.New("用户名或密码错误")
	}

	// 验证密码
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
		return "", errors.New("用户名或密码错误")
	}

	// 生成JWT token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"user_id":  user.ID,
		"username": user.Username,
		"exp":      time.Now().Add(time.Duration(s.config.Security.JWTExpire) * time.Second).Unix(),
	})

	// 签名token
	tokenString, err := token.SignedString([]byte(s.config.Security.JWTSecret))
	if err != nil {
		return "", err
	}

	return tokenString, nil
}

// GetUserInfo 获取用户信息
func (s *userServiceImpl) GetUserInfo(ctx context.Context, id uint) (*entity.User, error) {
	return s.userRepo.FindByID(ctx, id)
}

// UpdateUserInfo 更新用户信息
func (s *userServiceImpl) UpdateUserInfo(ctx context.Context, user *entity.User) error {
	return s.userRepo.Update(ctx, user)
}

// ChangePassword 修改密码
func (s *userServiceImpl) ChangePassword(ctx context.Context, id uint, oldPassword, newPassword string) error {
	// 查找用户
	user, err := s.userRepo.FindByID(ctx, id)
	if err != nil {
		return err
	}

	// 验证旧密码
	if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword)); err != nil {
		return errors.New("旧密码错误")
	}

	// 加密新密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
	if err != nil {
		return err
	}

	// 更新密码
	user.Password = string(hashedPassword)
	return s.userRepo.Update(ctx, user)
}

// ListUsers 获取用户列表
func (s *userServiceImpl) ListUsers(ctx context.Context, offset, limit int) ([]*entity.User, int64, error) {
	return s.userRepo.List(ctx, offset, limit)
}

// DeleteUser 删除用户
func (s *userServiceImpl) DeleteUser(ctx context.Context, id uint) error {
	return s.userRepo.Delete(ctx, id)
}
